﻿package
{
	import core.Config;
	import core.Model;
	import core.Util;
	import core.containers.CardContainer;
	import core.containers.ChipEffectContainer;
	import core.events.GameEvent;
	import core.manager.SoundManager;
	
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	
	
	
	/**
	 * 1.缺少16的sound
	 * 2.sound0错误
	 * 3.分牌错误
	 * 4.分牌播放声音错误
	 * 
	 * 
	 * 1.加保险功能
	 * 2.加额外的声音
	 * 3.计算点数
	 * 
	 * 
	 * 
	 * 1.双倍 加注的功能
	 * 
	 */ 
	public class Table extends MovieClip
	{
		public var playerCPU:PlayerTable;
		
		public var chipList:ChipList;
		
		public var buttonList:ButtonList;
		
		public var hintArrow:MovieClip;// 显示到哪个用户的按纽
		
		private  var chips:Array = [];// 所有添加筹码的列表{owner:owner};
		
		private var model:Model = Model.instance;
		
		public function Table()
		{
			super();
			this.stop();
			playerCPU.mouseEnabled = false;
			playerCPU.visible = false;
			this.hintArrow.mouseChildren = this.hintArrow.mouseEnabled = false;
			this.hintArrow.visible = false;
			SoundManager.instance.playBackground();
			SoundManager.instance.play("place_your_bets_please");
			this.addEventListener(Event.ADDED_TO_STAGE,addToStageHandler);
		}
		
		public function buttonClick(event:MouseEvent):void {
			var target:SimpleButton = event.target as SimpleButton;
			if(target == null){
				return;
			}
			var name:String = target.name;
			var index:int = int(name.slice(3,name.length));
			switch(index){
				case 0:
					this.repeatAndSend();
					break;
				case 1:
					this.repeat();
					break;
				case 2:
					this.reduction();
					break;
				case 3:
					this.send();
					break;
				case 4:
					this.double();
					break;
				case 5:
					this.clear();
					break;
				case 6:
					this.call();
					break;
				case 7:
					this.stopCall();
					break;
				case 8:
					this.sendDouble();
					break;
				case 9:
					this.split();
					break;
			}
		}
		
		private function sendDouble():void {
			var owner:int = model.first;
			var cardContainer:CardContainer = this.getCardContainer(owner);
			var total:Number = cardContainer.totalNumber;
			if(total > model.points){
				this.showNoCashPanel();
				return;
			}
			
			cardContainer.doubleabled = false;
			total = cardContainer.totalNumber;// 当前的点数
			this.updatePoints(-total);
			this.updateTake(total);
			cardContainer.sendDouble(this.chipList.getSelectedPosition(),sendDoubleCallback);
			this.buttonList.state = -1;
		}
		
		private function sendDoubleCallback():void {
			var owner:int = model.first;
			var cardContainer:CardContainer = this.getCardContainer(owner);
			cardContainer.addEventListener(GameEvent.SEND_CARD_COMPLETE,addCardCompleted);
			cardContainer.addCard();
		}
		
		private function nextSplit():void {
			var owner:int = Model.instance.first;
			var cardContainer:CardContainer = this.getCardContainer(owner);
			cardContainer.splitable = false;
			var nextOwner:int = owner + 6;
			var nextCardContainer:CardContainer = this.getCardContainer(nextOwner);// 添加 cardEffect
			nextCardContainer.splitable = false;
			nextCardContainer.copy(cardContainer.item.cardItemObject,cardContainer.item.v);
			model.insert(nextOwner);
			cardContainer.addEventListener(GameEvent.SEND_CARD_COMPLETE,showArrowHandler);
			cardContainer.addCard();
			
			nextCardContainer.addCard();// 这个也自动增加一张
		}
		
		private function showArrowHandler(event:GameEvent):void {
			var cardContainer:CardContainer = event.target as CardContainer;
			if(cardContainer){
				cardContainer.removeEventListener(GameEvent.SEND_CARD_COMPLETE,showArrowHandler);
			}
			this.adjustArrowPosition();
		}
		
		/**
		 * 如果是2个A的分牌,不能赌倍
		 * 如果不是2个A可以赌倍
		 */ 
		private function split():void {
			var owner:int = Model.instance.first;
			var cardContainer:CardContainer = this.getCardContainer(owner);
			var total:Number = cardContainer.totalNumber;
			if(total > model.points){
				this.showNoCashPanel();
				return;
			}
			var nextOwner:int = owner + 6;
			var nextCardContainer:CardContainer = this.getCardContainer(nextOwner);// 添加 cardEffect
			if(cardContainer.isTwoA){
				cardContainer.doubleabled = false;
				nextCardContainer.doubleabled = false;
			}
			cardContainer.split(nextSplit);
			total = cardContainer.totalNumber;// 当前分牌的点的总数
			this.updatePoints(-total);
			this.updateTake(total);
			this.buttonList.state = 0;
			cardContainer.insureable = false;
		}
		
		/**
		 * 重复下注
		 * 需要检测 一下是否点数够
		 */ 
		private function repeat():Boolean {
			var position:Point = this.chipList.getSelectedPosition();
			model.slice();// 分的牌不需要
			var result:Number = 0;
			var i:int = 0;
			var owner:int;
			var cardContainer:CardContainer;
			for(; i < model.players.length; i++){
				owner = model.players[i];
				cardContainer = this.getCardContainer(owner);
				result += cardContainer.realChips;
			}
			if(result > model.points){
				this.showNoCashPanel();
				model.players = [];
				this.buttonList.state = -1;
				return false;
			}
			i = 0;
			for(; i < model.players.length; i++){
				owner = model.players[i];
				cardContainer = this.getCardContainer(owner);
				cardContainer.repeat(position);
			}
			
			//this.updatePoints(-result);
			this.updateTake(result);
			this.buttonList.state = 4;// 显示到可以发牌的状态
			return true;
		}
		
		/**
		 * 重复下注和发牌
		 */ 
		private function repeatAndSend():void {
			var flag:Boolean = this.repeat();
			if(flag){
				this.send();
			}
		}
		
		private function addToStageHandler(event:Event):void {
			this.removeEventListener(Event.ADDED_TO_STAGE,addToStageHandler);
			this.createChildren();
			Model.instance.createCards();
			this.buttonList.addEventListener(MouseEvent.CLICK,buttonClick);
		}
		
		private function sendCardCompleted(event:GameEvent):void {
			var cardContainer:CardContainer = event.target as CardContainer; 
			cardContainer.removeEventListener(GameEvent.SEND_CARD_COMPLETE,sendCardCompleted);
			if(Model.instance.has){
				var owner:int = Model.instance.shift();
				this.addCardEffect(owner);
			}else {
				this.buttonList.state = -1;
				cardContainer = this.getCardContainer(this.playerCPU.owner);
				if(cardContainer.isA){// 如果电脑是A,玩家可以要保险
					Model.instance.copy();
				}
				this.showInsure();
			}
		}
		
		private function showInsure():void {
			if(model.has){
				var insurancePanel:InsurancePanel = new InsurancePanel();
				insurancePanel.addEventListener(GameEvent.SET_INSURE_TYPE,setInsureHandler);
				this.addChild(insurancePanel);
				return;
			}else {
				Model.instance.copy();
				this.checkMaxPoints();
				this.adjustArrowPosition();
			}
		}
		
		public function caclulateInsureValue(value:CardContainer):void {
			var total:Number = value.totalNumber * 0.5;
			if(total > model.points){
				this.showNoCashPanel();
				return;
			}
			value.caclulateInsureValue(this.chipList.getSelectedPosition());
			this.updateTake(value.insureValue);
			this.updatePoints(-value.insureValue);
		}
		/**
		 * 4 所有都不要保险
			3 当前这个不要保险
			2 全部要保险
			1 当前的要保险
		 */
		private function setInsureHandler(event:GameEvent):void {
			var insurancePanel:InsurancePanel = event.target as InsurancePanel;
			var type:int = insurancePanel.type;
			var owner:int = Model.instance.first;
			var targetCardContainer:CardContainer = this.cardsContainer.getChildByName(owner.toString()) as CardContainer;
			var i:int = 0;
			if(type == 1){
				targetCardContainer.insureable = false;
				this.caclulateInsureValue(targetCardContainer);
				model.shift();
			}else if(type == 2){
				while(model.has){
					owner = model.shift();
					targetCardContainer = this.getCardContainer(owner);
					targetCardContainer.insureable = false;
					this.caclulateInsureValue(targetCardContainer);
				}
			}else if(type == 3){
				model.shift();
				targetCardContainer.insureable = false;
			}else if(type == 4){
				while(model.has){
					owner = model.shift();
					targetCardContainer = this.getCardContainer(owner);
					targetCardContainer.insureable = false;
				}
			}
			insurancePanel.dispose();
			setTimeout(this.showInsure,500);
		}
		
		private function addCardEffect(owner:int,loopabled:Boolean = true,callback:Function = null):void {
			var cardContainer:CardContainer = this.cardsContainer.getChildByName(owner.toString()) as CardContainer;
			cardContainer.addEventListener(GameEvent.SEND_CARD_COMPLETE,sendCardCompleted);
			cardContainer.addCard();
		}
		
		/**
		 * 检测玩家是否是21点,如果是21点直接跳过 
		 * 
		 */		
		private function checkMaxPoints():void {
			for(var i:int = 0; i < Model.instance.players.length; i++){
				var owner:int = Model.instance.players[i];
				var cardContainer:CardContainer = this.getCardContainer(owner);
				if(cardContainer.points == Config.MAX_POINTS){
					cardContainer.playSound();
					Model.instance.players.splice(i,1);
				}
			}
		}
		
		public var nextabled:Boolean = true;// 是否显示下一个
		/**
		 * 显示具体小箭头的位置的位置
		 * @param value
		 * 
		 */		
		private function adjustArrowPosition(soundabled:Boolean = true,stateabled:Boolean = true):void {
			if(Model.instance.has){// 玩家全部是21点
				this.hintArrow.visible = true;
				var owner:int = Model.instance.first;
				var cardContainer:CardContainer = this.getCardContainer(owner);
				if(stateabled){
					if(cardContainer.canSplit){
						this.buttonList.state = 6;
					}else {
						this.buttonList.state = 0;
					}
					if(cardContainer.doubleabled){
						this.buttonList.showDoubleButton();
					}else {
						this.buttonList.hideDoubleButton();
					}
				}
				var point:Point = Config.CARD_ARROW_POINTS[owner];
				var index:int = this.getChildIndex(this.hintArrow);
				var maxIndex:int = this.numChildren - 1;
				this.swapChildrenAt(index,maxIndex);
				this.hintArrow.x = point.x;
				this.hintArrow.y = point.y;
				if(soundabled){
					cardContainer.playSound();
				}
			}else {
				if(this.nextabled){
					this.showNextPlayer();
				}
			}
		}
		
		
		/**
		 * 配置一些事件,比如按纽的点击事件
		 * 这里使用最简单的办法,按纽先添加起来,然后隐藏,需要的时候再显示出来即可
		 */ 
		
		public function reinit():void {
			var i:int = 0;
			for(; i < Config.MAX_USERS; i++){
				var childName:String = "player" + i;
				var playerTable:PlayerTable = this[childName] as PlayerTable;
				playerTable.owner = i;	
				playerTable.position = Config.PLAYER_TABLE_POSITION[i];
				playerTable.removeEventListener(MouseEvent.CLICK,this.addChipHandler);
				playerTable.addEventListener(MouseEvent.CLICK,this.addChipHandler);
				playerTable.init();
			}
			playerCPU.owner = Config.CPU_OWNER;
			
			i = 0;
			for(; i < cardsContainer.numChildren; i++){
				var cardContainer:CardContainer = cardsContainer.getChildAt(i) as CardContainer;
				cardContainer.init();
			}
		}
		
		private function createChildren():void {
			var i:int = 0;
			for(; i < Config.MAX_USERS; i++){
				var childName:String = "player" + i;
				var playerTable:PlayerTable = this[childName] as PlayerTable;
				playerTable.owner = i;	
				playerTable.position = Config.PLAYER_TABLE_POSITION[i];
				playerTable.removeEventListener(MouseEvent.CLICK,this.addChipHandler);
				playerTable.addEventListener(MouseEvent.CLICK,this.addChipHandler);
				playerTable.init();
			}
			playerCPU.owner = Config.CPU_OWNER;
			i = 0;
			cardsContainer = new Sprite();
			cardsContainer.mouseChildren = cardsContainer.mouseEnabled = false;
			this.addChildAt(cardsContainer,this.numChildren - 1);
			for(; i < Config.PLAYER_TABLE_POSITION.length; i++){
				var cardContainer:CardContainer = new CardContainer();
				cardContainer.owner = i;
				var position:Point = Config.PLAYER_TABLE_POSITION[i];
				cardContainer.x = position.x;
				cardContainer.y = position.y;
				cardContainer.name = i.toString();
				cardContainer.addEventListener(GameEvent.UPDATE_PLAYER_TABLE_STATE,updatePlayerTableState);
				cardsContainer.addChild(cardContainer);
			}
		}
		
		private function updatePlayerTableState(event:GameEvent):void {
			var cardContainer:CardContainer = event.target as CardContainer;
			var owner:int = cardContainer.owner;
			if(cardContainer.totalNumber == 0){
				var childName:String = "player" + owner;
				if(this.hasOwnProperty(childName)){
					var playerTable:PlayerTable = this[childName];
					playerTable.init();
				}
			}
		}
		
		private var cardsContainer:Sprite;
		
		override public function set enabled(value:Boolean):void {
			super.enabled = value;
			this.chipList.enabled = value;
			for(var i:int = 0; i < Config.MAX_USERS; i++){
				var childName:String = "player" + i;
				var playerTable:PlayerTable = this[childName] as PlayerTable;
				playerTable.enabled = value;
			}
		}
		
		public function send():void {
			this.enabled = false;// 不能再点了
			Model.instance.sort();
			Model.instance.conact();
			var temp:Array = Model.instance.players.concat();
			model.addOwner(this.playerCPU.owner);
			model.addArray(temp);
			var owner:int = Model.instance.shift();
			this.addCardEffect(owner);
			this.buttonList.state = -1;
			this.updatePoints(-this.totalPoints);
		}
		
		private function updatePoints(value:Number):void {
			model.update(value);
			this.dispatchEvent(new GameEvent(GameEvent.UPDATE_POINTS,true));
		}
		
		public function get totalPoints():Number {
			var result:Number = 0;
			for(var i:int = 0; i < this.cardsContainer.numChildren; i++){
				var cardContainer:CardContainer = this.getCardContainer(i);
				result += cardContainer.totalNumber;
			}
			return result;
		}
		
		/**
		 * 双倍
		 */ 
		public function double():void {
			var total:Number = this.totalPoints * 2;
			if(total > Model.instance.points){
				this.showNoCashPanel();
				return;
			}
			for(var i:int = 0; i < Model.instance.players.length; i++){
				var owner:int = Model.instance.players[i];
				var cardContainer:CardContainer = this.cardsContainer.getChildByName(owner.toString()) as CardContainer;
				this.updateTake(cardContainer.totalNumber);
				cardContainer.double(this.chipList.getSelectedPosition());
				this.chips.push({owner:owner});
				
				
			}
		}
		
		private function showNoCashPanel():void {
			var cashPanel:NoCashPanel = new NoCashPanel();
			this.addChild(cashPanel);
		}
		
		/**
		 * 复原
		 */ 		
		public function reduction():void {
			var position:Point = this.chipList.getSelectedPosition();
			var object:Object = this.chips.shift();
			var owner:int = object.owner;
			var cardContainer:CardContainer = this.getCardContainer(owner);
			this.updateTake(-cardContainer.totalNumber);
			cardContainer.reduction(position)
			if(!Model.instance.has){
				this.buttonList.state = -1;// TODO 状态有问题
			}
			
		}
		
		/**
		 * 清除所有下注
		 */ 
		public function clear():void {
			while(Model.instance.players.length > 0){
				var owner:int = model.shift();
				var cardContainer:CardContainer = this.getCardContainer(owner);
				cardContainer.clear(this.chipList.getSelectedPosition());
			}
			this.updateTake(-model.take);
			this.buttonList.state = -1;
		}
		
		public function getCardContainer(owner:int):CardContainer {
			return this.cardsContainer.getChildByName(owner.toString()) as CardContainer;
		}
		
		/**
		 * 叫牌
		 */ 
		public function call(showPanel:Boolean = true):void {
			var cardContainer:CardContainer = this.getCardContainer(this.playerCPU.owner);
			var owner:int = Model.instance.first;;
			var targetCardContainer:CardContainer = this.cardsContainer.getChildByName(owner.toString()) as CardContainer;
			var total:Number = 0;
			if(!showPanel){
				if(model.hintMode == 0){
					model.shift();
					this.adjustArrowPosition();
					return;
				}
			}
			var points:int = targetCardContainer.points;
			if(showPanel){
				if(points >= Config.CPU_MAX_POINTS){
					if(model.hintMode == 1){
						var hintPanel:InsureHintPanel = new InsureHintPanel();
						hintPanel.callback = this.call;
						this.addChild(hintPanel);
						return;
					}
				}
			}
			targetCardContainer.addEventListener(GameEvent.SEND_CARD_COMPLETE,addCardCompleted);
			targetCardContainer.addCard();
			this.buttonList.state = -1;
		}
		
		
		private function addCardCompleted(event:GameEvent):void {
			var cardContainer:CardContainer = event.target as CardContainer; 
			cardContainer.removeEventListener(GameEvent.SEND_CARD_COMPLETE,addCardCompleted);
			this.checkBomb();
		}
		
		/**
		 * 检测玩家是否已经爆机了,如果爆了就删除掉 
		 * 
		 */		
		private function checkBomb():void {
			var owner:int = Model.instance.first;
			var cardContainer:CardContainer = this.getCardContainer(owner);
			var points:int = cardContainer.points;
			if(points > Config.MAX_POINTS){// > 21 爆了
				cardContainer.bomb(this.checkNextState);
			}else if(points == Config.MAX_POINTS) {// 正好21点
				this.buttonList.state = 0;
				model.shift();
				setTimeout(this.showNextPlayer,300);
			}else {
				if(cardContainer.sendabled){
					this.buttonList.state = 0;
				}else {
					model.shift();
					setTimeout(this.showNextPlayer,300);
				}
			}
		}
		
		private function checkNextState():void {
			/*var total:Number = this.totalPoints;
			if(total > Model.instance.points){
				this.showNoCashPanel();
				return;
			}*/
			if(model.has){
				clearID = setTimeout(this.showNextPlayer,500);
			}else {
				setTimeout(checkSendCPU,1000);
			}
		}
		
		private function checkSendCPU():void {
			if(this.isBomb){// 如果所有的都bomb了,那么,电脑就直接不补牌了
				this.showResult();
			}else {
				this.sendCPUFunc();
			}
		}
		
		public function get isBomb():Boolean {
			for(var i:int = 0; i < this.cardsContainer.numChildren; i++){
				var cardContainer:CardContainer = this.getCardContainer(i);
				if(cardContainer.owner != this.playerCPU.owner){
					if(cardContainer.getCardObjectItems().length > 0){
						return false;
					}
				}
			}
			return true;
		}
		
		/**
		 * 发牌给庄家,当大于一定的数值时,庄家的牌就不再要牌了 
		 * 
		 */		
		private var lastChipEffect:ChipEffectContainer;
		private function sendCPUFunc(event:GameEvent = null):void {
			var cardContainer:CardContainer
			if(event){
				cardContainer = event.target as CardContainer;
				cardContainer.removeEventListener(GameEvent.SEND_CARD_COMPLETE,sendCPUFunc);
			}else {
				cardContainer = this.cardsContainer.getChildByName(this.playerCPU.owner.toString()) as CardContainer;
			}
			clearTimeout(clearID);
			this.buttonList.state = -1;
			var points:int = cardContainer.points;
			if(points >= Config.CPU_MAX_POINTS){
				Model.instance.copy(false);
				this.nextabled = false;
				lastChipEffect = new ChipEffectContainer(true);
				lastChipEffect.x = Config.LAST_CHIP_EFFECT_POSITION.x;
				lastChipEffect.y = Config.LAST_CHIP_EFFECT_POSITION.y;
				this.addChild(lastChipEffect);
				setTimeout(this.showResult,500);
			}else {
				clearID = setTimeout(this.showNextPlayer,800);// 继续发给庄家牌
			}
		}
		
		/**
		 * 游戏结束,计算庄家的点数,和相应的玩家点数对比 
		 * @param event
		 * 
		 */		
		
		public function get cpuCardContainer():CardContainer {
			return this.getCardContainer(this.playerCPU.owner);
		}
		
		private var isRenew:Boolean;
   		private function showResult():void {
			if(isRenew){
				this.renew();
				//this.updatePoints(this.lastChipEffect.total);
				return;
			}
			var owner:int = -1;
			if(Model.instance.has){// TODO
				owner = Model.instance.first;
				var cardContainer:CardContainer = this.getCardContainer(owner);
				
				if(this.cpuCardContainer.isBlackJack){
					if(cardContainer.insureValue != 0){// 如果玩家买了保险的话,那么就加上这个钱
						cardContainer.addInsure(this.lastChipEffect,cardContainer.insureValue * 2);
						//this.updatePoints(cardContainer.insureValue * 2);// 玩家得到钱的2倍
					}else {
						cardContainer.insureFunc();
					}
				}else {
					cardContainer.insureFunc();
				}
				var count:int = cardContainer.points;
				
				if(count == 0){
					model.shift();
					this.showResult();
					return;
				}
				var points:int = this.cpuCardContainer.points;
				this.adjustArrowPosition(false,false);
				var state:int = cardContainer.checkBigSmall(cpuCardContainer);
				
				if(state == 1){// 庄家赢
					cardContainer.bomb(this.showResult);
				}else if(state == -1){// 玩家赢
					cardContainer.win(this.lastChipEffect,this.showResult);
				}else {
					cardContainer.dogfall(this.lastChipEffect,this.showResult);
				}
			}else{
				owner = this.playerCPU.owner;
				isRenew = true;
				this.cpuCardContainer.remove(this.showResult);
			}
			this.buttonList.state = -1;
		}
		
		/**
		 * 停止叫牌
		 */ 
		private var clearID:uint;
		
		public function stopCall():void {
			model.shift();
			this.buttonList.state = -1;
			clearID = setTimeout(showNextPlayer,500);
		}
		
		private function showNextPlayer():void {
			clearTimeout(clearID);
			this.hintArrow.visible = false;
			if(Model.instance.has){
				this.buttonList.state = 0;
				this.adjustArrowPosition();
			}else {
				var cardContainer:CardContainer = this.cardsContainer.getChildByName(this.playerCPU.owner.toString()) as CardContainer;
				cardContainer.addEventListener(GameEvent.SEND_CARD_COMPLETE,sendCPUFunc);
				cardContainer.addCard();
			}
		}
		
		private function renew():void {
			if(this.lastChipEffect){
				this.updatePoints(this.lastChipEffect.total);
			}
			this.updateTake(-model.take);// 清空take
			this.isRenew = false;
			this.nextabled = true;
			this.hintArrow.visible = false;
			clearTimeout(clearID);
			this.removeAllChildren();
			Util.removeChild(lastChipEffect);
			this.chipList.enabled = true;
			this.enabled = true;
			Model.instance.createCards();
			this.reinit();
			this.buttonList.state = 5;
			SoundManager.instance.play("place_your_bets_please");
		}
		
		private function removeAllChildren():void {
			this.buttonList.state = -1;
		}
		
		public function updateTake(value:Number):void {
			model.take += value;
			this.dispatchEvent(new GameEvent(GameEvent.UPDATE_TAKE,true));
		}
		
		private function addChipHandler(event:MouseEvent):void {
			var total:Number = this.totalPoints + this.chipList.selected.data.value;
			if(total > Model.instance.points){
				this.showNoCashPanel();
				return;
			}
			var target:PlayerTable = event.target as PlayerTable;
			if(target) {
				this.buttonList.state = 4;//启用第一组按钮
				Model.instance.addOwner(target.owner);
				var cardContainer:CardContainer = this.cardsContainer.getChildByName(target.owner.toString()) as CardContainer;
				cardContainer.addChip(this.chipList.getSelectedPosition(),this.chipList.selected.data);
				this.chips.push({owner:target.owner});
				this.updateTake(this.chipList.selected.data.value);
			}
		}
	}
}